package self

import (
	"database/sql"
	"fmt"

	"gitee.com/tinkler/yunfei/self/driver"
	"gitee.com/tinkler/yunfei/self/register"
)

// Manager 管理器
type Manager struct {
	db         *sql.DB
	driverName string
	driver     driver.Driver
	register.Registe
}

// NewManager 新建管理器
func NewManager(opts Options) (*Manager, error) {
	m := Manager{}
	driversMu.RLock()
	driver, ok := drivers[opts.DriverName]
	driversMu.RUnlock()
	if !ok {
		return nil, fmt.Errorf("self: unknown driver %q (forgotten import?)", opts.DriverName)
	}
	m.driver = driver
	m.driverName = opts.DriverName

	pq, err := sql.Open("postgres", opts.DataSourceName)
	if err != nil {
		panic("self:open postgres db error")
	}
	m.db = pq
	m.RegisterUser(opts.UserModel)

	return &m, nil
}

// VerifyUser 验证用户
func (m *Manager) VerifyUser(user interface{}) (bool, error) {
	m.ResetRole()
	app, ok := user.(register.User)
	if !ok {
		panic("self:user has no method verify")
	}
	return app.Verify(m.db)
}

// SetRole set the postgres rolename active
func (m *Manager) SetRole(rolename string) error {
	result, err := m.db.Exec("SET ROLE " + rolename)
	if err != nil {
		return fmt.Errorf("set role %s errors:%s", rolename, err.Error())
	}
	_, err = result.RowsAffected()
	if err != nil {
		return fmt.Errorf("set role:%s", err.Error())
	}
	return nil
}

// ResetRole 重置权限名
func (m *Manager) ResetRole() {
	m.db.Exec("RESET ROLE;")
}

func (m *Manager) GetDB() *sql.DB {
	return m.db
}

func (m *Manager) CloseDB() {
	m.db.Close()
}
